﻿using System;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reactive.Subjects;
using System.Threading.Tasks;
using AForge.Video;
using AForge.Video.FFMPEG;
using Clancy.Interfaces;
using Microsoft.Win32;

namespace Clancy.Bl.VideoProvider
{
    class FileVideoSourceHandler : IVideoSourceHandler
    {
        private string m_FileName;
        private readonly BehaviorSubject<Bitmap> m_CurrentFrame = new BehaviorSubject<Bitmap>(null);
        private VideoFileSource m_VideoFileSource;

        public FileVideoSourceHandler(string filename)
        {
            LoadFile(filename);
        }

        private void LoadFile(string filename)
        {
            m_FileName = filename;
            if (!File.Exists(m_FileName))
                return;

            m_VideoFileSource = new VideoFileSource(m_FileName);
            m_VideoFileSource.NewFrame += OnNewFrameRead;
            m_VideoFileSource.PlayingFinished += OnVideoStopped;
            m_VideoFileSource.VideoSourceError += OnVideoSourceError;
        }

        public IObservable<Bitmap> IncomingBitmapFrame
        {
            get { return m_CurrentFrame; }            
        }
        public Task<bool> Open()
        {
            if (!File.Exists(m_FileName))
                return Task.FromResult(false);

            m_VideoFileSource.Start();

            return Task.FromResult(true);
        }

        private void OnVideoSourceError(object sender, VideoSourceErrorEventArgs eventargs)
        {
            
        }

        private void OnVideoStopped(object sender, ReasonToFinishPlaying reason)
        {
            Close();
            Open();
        }

        private void OnNewFrameRead(object sender, NewFrameEventArgs eventargs)
        {
            m_CurrentFrame.OnNext(eventargs.Frame);
        }

        public Task<bool> Close()
        {
            if (m_VideoFileSource == null)
                return Task.FromResult(false);

            m_VideoFileSource.Stop();
            return Task.FromResult(true);
        }

        public async void ShowSettingsDialog()
        {
            OpenFileDialog openFileDialog = new OpenFileDialog {Filter = "Avi files (*.avi)|*.avi|All files (*.*)|*.*"};
            bool? dlgResult = openFileDialog.ShowDialog();
            if ((dlgResult != null) && (dlgResult.Value))
            {
                await Close();

                LoadFile(openFileDialog.FileName);
                
                await Open();
            }
        }
    }
}
